package org.example.carplatoon.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.example.carplatoon.common.CustomException;
import org.example.carplatoon.dto.UseEmp;
import org.example.carplatoon.entity.*;
import org.example.carplatoon.common.R;
import org.example.carplatoon.dto.carPlatoonDto;
import org.example.carplatoon.service.carBindService;
import org.example.carplatoon.service.carPlatoonService;
import org.example.carplatoon.service.carService;
import org.example.carplatoon.service.employeeService;
import org.example.carplatoon.service.userService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;


import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@RequestMapping
@RestController
public class carPlatoonController {

    @Autowired
    private carPlatoonService carPlatoonService;

    @Autowired
    private userService userService;

    @Autowired
    private carBindService carBindService;


    @Autowired
    private carService carService;

    @Autowired
    private employeeService employeeService;


    @Value("${car.path}")
    private String basePath;

    /**
     * 管理员首页获取部分车队数据
     *
     * @return
     */
    @GetMapping("/getPartialPlatoon")
    @Transactional
    public R<List<carPlatoonDto>> getpartialPlatoon() {
        LambdaQueryWrapper<carPlatoon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(carPlatoon::getStatus, 1);
        List<carPlatoon> carPlatoonList = carPlatoonService.list(queryWrapper);
        if (carPlatoonList.isEmpty()) {
            return R.error("暂无车队数据");
        }
        List<carPlatoonDto> carPlatoonDtoList = carPlatoonList.stream().map((item) -> {
            carPlatoonDto carPlatoonTmp = new carPlatoonDto();
            BeanUtils.copyProperties(item, carPlatoonTmp);

            user user = userService.getById(carPlatoonTmp.getUserId());
            if(user == null) {
                throw new CustomException("数据错误");
            }
            carPlatoonTmp.setAvatar(user.getAvatar());
//            返回的是用户名
            carPlatoonTmp.setLeaderName(user.getName());
            return carPlatoonTmp;
        }).collect(Collectors.toList());


        if (carPlatoonDtoList.size() > 4) {
            carPlatoonDtoList = carPlatoonDtoList.subList(0, 3);
        }

        return R.success("获取数据成功", carPlatoonDtoList);
    }


    /**
     * 分页查询所有车队信息，可以根据领队用户名或status筛选
     *
     * @param page
     * @param pageSize
     * @param name
     * @param status
     * @return
     */
    @GetMapping("/getAllPlatoon")
    @Transactional
    public R<Page> getAllPlatoon(int page, int pageSize, String name, Integer status) {
        log.info("page = {}, pageSize = {}, name = {}, status = {}", page, pageSize, name, status);
        List<Long> userId = new ArrayList<>();

        Page<carPlatoon> pageInfo = new Page(page, pageSize);
        Page<carPlatoonDto> carPlatoonDtoPage = new Page<>();

//        有名字的话找出对应的id
        if (StringUtils.hasText(name)) {
            LambdaQueryWrapper<user> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userLambdaQueryWrapper.likeRight(user::getName, name);
            List<user> User = userService.list(userLambdaQueryWrapper);
            if (User.isEmpty()) {
                return R.success("未找到该用户数据", null);
            }
            for (org.example.carplatoon.entity.user user : User) {
                userId.add(user.getId());
            }
        }
        LambdaQueryWrapper<carPlatoon> queryWrapper = new LambdaQueryWrapper<>();
//        添加过滤条件：用户id
        queryWrapper.in(!userId.isEmpty(), carPlatoon::getUserId, userId);
//        添加过滤条件：车队状态status
        queryWrapper.eq(status != null, carPlatoon::getStatus, status);
//        添加排序条件
        queryWrapper.orderByDesc(carPlatoon::getCreateTime);

//        查询车队信息
        carPlatoonService.page(pageInfo, queryWrapper);
//        复制到扩展dto
        BeanUtils.copyProperties(pageInfo, carPlatoonDtoPage, "records");
//        根据用户id找出leaderName和avatar
        List<carPlatoon> records = pageInfo.getRecords();
        List<carPlatoonDto> list = records.stream().map((item) -> {
            carPlatoonDto CarPlatoonDto = new carPlatoonDto();
            BeanUtils.copyProperties(item, CarPlatoonDto);

            Long id = item.getUserId();
//          根据id查询对应信息
            user user = userService.getById(id);

            if (user != null) {
//                返回设置的是用户名
                String leaderName = user.getName();
                String avatar = user.getAvatar();
                CarPlatoonDto.setLeaderName(leaderName);
                CarPlatoonDto.setAvatar(avatar);
            }
            return CarPlatoonDto;
        }).collect(Collectors.toList());
        carPlatoonDtoPage.setRecords(list);
        return R.success("success", carPlatoonDtoPage);
    }

    /**
     * 获取所有车队位置信息
     *
     * @return
     */
    @GetMapping("/mapGetPoint")
    @Transactional
    public R<List<Map<String, Object>>> mapGetPoint() {
        LambdaQueryWrapper<carPlatoon> carPlatoonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carPlatoonLambdaQueryWrapper.eq(carPlatoon::getStatus, 1);
        List<carPlatoon> carPlatoonList = carPlatoonService.list(carPlatoonLambdaQueryWrapper);

        if (!carPlatoonList.isEmpty()) {
            List<Map<String, Object>> list = carPlatoonList.stream().map((item) -> {
                Map<String, Object> pointInfo = new HashMap<>();
                Long platoonId = item.getId();
                Long userId = item.getUserId();
                pointInfo.put("id", platoonId.toString());
                pointInfo.put("userId", userId.toString());

                LambdaQueryWrapper<carBind> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(carBind::getPlatoonId, platoonId);
                queryWrapper.eq(carBind::getUserId, userId);
                carBind carBind = carBindService.getOne(queryWrapper);
                if (carBind != null) {
                    pointInfo.put("curLongitude", carBind.getCurLongitude());
                    pointInfo.put("curLatitude", carBind.getCurLatitude());
                } else {
                    pointInfo.put("curLongitude", null);
                    pointInfo.put("curLatitude", null);
                }
                return pointInfo;
            }).collect(Collectors.toList());
            return R.success("success", list);
        } else {
            return R.error("暂无车队运行中");
        }
    }


    @GetMapping("/getPointInfo")
    @Transactional
    public R<Map<String, Object>> getGetPointInfo(Long userId) {


        // todo: 我还没写健壮性测试
        if (userId == null) {
            return R.error("信息不能为空");
        }

//        System.out.println(userId);
        Map<String, Object> result = new HashMap<>();


        //再查carbind表
        LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carBindLambdaQueryWrapper.eq(carBind::getUserId, userId);
        carBind one3 = carBindService.getOne(carBindLambdaQueryWrapper);
        if (one3 == null) {
            //查用户看是否有这个用户
            LambdaQueryWrapper<user> userLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            userLambdaQueryWrapper1.eq(user::getId, userId);
            user one5 = userService.getOne(userLambdaQueryWrapper1);
            if (one5 == null) {
                return R.error("没有这个用户");
            } else {
                return R.error("这个用户未加入车队");
            }
        }
        Long carId = one3.getCarId();
        result.put("curLongitude", one3.getCurLongitude());
        result.put("curLatitude", one3.getCurLatitude());
        Long platoonIdreal = one3.getPlatoonId();

        //再查车队表(carplatoon)
        LambdaQueryWrapper<carPlatoon> carPlatoonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carPlatoonLambdaQueryWrapper.eq(carPlatoon::getId, platoonIdreal);
        carPlatoon one1 = carPlatoonService.getOne(carPlatoonLambdaQueryWrapper);

        result.put("platoonId", one1.getId().toString());
        result.put("startPoint", one1.getStartPoint());
        result.put("endPoint", one1.getEndPoint());
        result.put("status", one1.getStatus());
        result.put("creatTime", one1.getCreateTime());
        result.put("endTime", one1.getEndTime());


        //再查用户表(user)
        LambdaQueryWrapper<user> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(user::getId, userId);
        user one2 = userService.getOne(userLambdaQueryWrapper);
        result.put("userName", one2.getUserName());
        result.put("sex", one2.getSex());
        result.put("phoneNum", one2.getPhoneNum());
        result.put("address", one2.getAddress());
        result.put("avatar", one2.getAvatar());

        //先查车(car)
        LambdaQueryWrapper<car> carLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carLambdaQueryWrapper.eq(car::getId, carId);
        car one = carService.getOne(carLambdaQueryWrapper);
        result.put("carPlate", one.getCarPlate());
        result.put("color", one.getColor());
        result.put("id", one.getId().toString());

        return R.success("success", result);
    }


    @GetMapping("/carInfo")
    @Transactional
    public R<Page> getcarInfo(int page, int pageSize) {
        Page<car> pageInfo = new Page(page, pageSize);


        //        查询车队信息
        Page<car> page1 = carService.page(pageInfo);

        return R.success("success", page1);
    }


    @PostMapping("/createPlatoon")
    @Transactional
    public R<Map<String, Object>> createPlatoon(@RequestBody carBind carbind) {
        Long userId = carbind.getUserId();
        Long carId = carbind.getCarId();

        user user = userService.getById(userId);
        if (user == null) {
            return R.error("用户不存在");
        }

        car car = carService.getById(carId);
        if (car == null) {
            return R.error("绑定车辆不存在");
        }

        BigDecimal platoonSpeed = carbind.getPlatoonSpeed();
        BigDecimal platoonSpacing = carbind.getPlatoonSpacing();

        // 验证车速和安全距离的逻辑
        if (platoonSpeed.compareTo(new BigDecimal("100")) > 0) {
            if (platoonSpacing.compareTo(new BigDecimal("100")) < 0) {
                return R.error("车速超过100km/h时，安全距离应大于等于100米");
            }
        } else if (platoonSpeed.compareTo(new BigDecimal("60")) >= 0) {
            if (!(platoonSpacing.compareTo(platoonSpeed) >= 0)) {
                return R.error("车速在60km/h到100km/h之间，安全距离应大于等于车速");
            }
        } else if (platoonSpeed.compareTo(new BigDecimal("50")) >= 0) {
            if (platoonSpacing.compareTo(new BigDecimal("50")) < 0) {
                return R.error("车速在50km/h到60km/h之间，安全距离应大于等于50米");
            }
        } else {
            if (platoonSpacing.compareTo(new BigDecimal("30")) < 0) {
                return R.error("车速低于50km/h，安全距离应大于等于30米");
            }
        }
        // 查询是否存在该用户的车队
        carBind existingUserBind = carBindService.getOne(new LambdaQueryWrapper<carBind>().eq(carBind::getUserId, userId));
        if (existingUserBind != null) {
            if (existingUserBind.getCarId().equals(carId)) {
                return R.error("已经存在该用户绑定表");
            } else {
                return R.error("该用户已绑定车辆");
            }
        }

        // 查询是否存在该车辆的绑定信息
        carBind existingCarBind = carBindService.getOne(new LambdaQueryWrapper<carBind>().eq(carBind::getCarId, carId));
        if (existingCarBind != null) {
            return R.error("该车辆已经绑定其他用户");
        }

        // 创建车队信息
        carPlatoon carPlatoon = new carPlatoon();
        carPlatoon.setCarNum(1);
        carPlatoon.setPlatoonSpacing(carbind.getPlatoonSpacing());
        carPlatoon.setPlatoonSpeed(carbind.getPlatoonSpeed());
        carPlatoon.setUserId(userId);
        carPlatoon.setStatus(1);
        carPlatoon.setStartPoint(carbind.getStartPoint());
        carPlatoon.setEndPoint(carbind.getEndPoint());
//        carPlatoon.setEndTime(LocalDateTime.now());

        carPlatoonService.save(carPlatoon);

        Long id = carPlatoon.getId();
        carbind.setPlatoonId(id);
        carbind.setPreCar(0L);

        carBindService.save(carbind);

        Map<String, Object> map = new HashMap<>();
        map.put("name", user.getName());
        map.put("id", id.toString());
        map.put("carNum", carPlatoon.getCarNum());

        return R.success("获取信息成功", map);
    }


    @PostMapping("/joinPlatoon")
    @Transactional
    public R<Map<String, Object>> joinPlatoon(@RequestBody carBind carbind) {


        Long id = carbind.getId();
        LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carBindLambdaQueryWrapper.eq(carBind::getPlatoonId, id).orderByDesc(carBind::getCreateTime).last("limit 1");

        carBind one = carBindService.getOne(carBindLambdaQueryWrapper);
//        System.out.println(one.getId());
        if (one == null) {
            return R.error("输入车队邀请码有误");
        }

        //查看是否有用户
        LambdaQueryWrapper<carBind> carBindLambdaQueryWrapperuser = new LambdaQueryWrapper<>();
        carBindLambdaQueryWrapperuser.eq(carBind::getUserId, carbind.getUserId());
        carBind one2 = carBindService.getOne(carBindLambdaQueryWrapperuser);
        if (one2 != null) {
            return R.error("该用户已经加入车队");
        }
        //查看是否有车在车中
        LambdaQueryWrapper<carBind> carBindLambdaQueryWrappercar = new LambdaQueryWrapper<>();
        carBindLambdaQueryWrappercar.eq(carBind::getCarId, carbind.getCarId());
        carBind one3 = carBindService.getOne(carBindLambdaQueryWrappercar);
        if (one2 != null) {
            return R.error("该车已经在车队中");
        }


        carBind carBind1 = new carBind();
        carBind1.setPreCar(one.getCarId());
        carBind1.setCarId(carbind.getCarId());
        carBind1.setPlatoonId(one.getPlatoonId());
        carBind1.setUserId(carbind.getUserId());
        carBind1.setCurLatitude(carbind.getCurLatitude());
        carBind1.setCurLongitude(carbind.getCurLongitude());


        boolean save = carBindService.save(carBind1);
        if (save) {
            LambdaQueryWrapper<carPlatoon> carPlatoonLambdaQueryWrapper = new LambdaQueryWrapper<>();
            carPlatoonLambdaQueryWrapper.eq(carPlatoon::getId, one.getPlatoonId());
            carPlatoon one1 = carPlatoonService.getOne(carPlatoonLambdaQueryWrapper);
            Integer carNum = one1.getCarNum();
            //更新车队中的车的数据+1
            UpdateWrapper<carPlatoon> carPlatoonUpdateWrapper = new UpdateWrapper<>();
            carPlatoonUpdateWrapper.eq("id", one.getPlatoonId()).set("car_num", carNum + 1);
            carPlatoonService.update(null, carPlatoonUpdateWrapper);
            return R.success("加入成功", null);
        } else {
            return R.error("加入失败");
        }

    }

    @PostMapping("/quitPlatoon")
    @Transactional
    public R<Map<String, Object>> quitPlatoon(@RequestBody carBind carbind) {
        Long userId = carbind.getUserId();
        Long platoonId = carbind.getPlatoonId();
        LambdaQueryWrapper<carPlatoon> carPlatoonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carPlatoonLambdaQueryWrapper.eq(carPlatoon::getId, platoonId).eq(carPlatoon::getUserId, userId).eq(carPlatoon::getStatus, 1);

        carPlatoon one = carPlatoonService.getOne(carPlatoonLambdaQueryWrapper);

        //删除领队
        if (one != null) {


            LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper = new LambdaQueryWrapper<>();
            carBindLambdaQueryWrapper.eq(carBind::getPlatoonId, carbind.getPlatoonId());
            boolean remove = carBindService.remove(carBindLambdaQueryWrapper);
            if (remove) {
                //更新车队中的status为0结束
                UpdateWrapper<carPlatoon> carPlatoonUpdateWrapper = new UpdateWrapper<>();
                carPlatoonUpdateWrapper.eq("id", carbind.getPlatoonId()).set("status", 0).set("end_time", LocalDateTime.now());

                carPlatoonService.update(null, carPlatoonUpdateWrapper);
                return R.success("删除领队成功", null);
            }

            return R.error("error");
            //删除普通用户
        } else {
            //找到删除车的前驱ID
            LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            carBindLambdaQueryWrapper1.eq(carBind::getUserId, userId);
            carBind one1 = carBindService.getOne(carBindLambdaQueryWrapper1);
            if (one1 == null) {
                return R.error("用户没有加入车队");
            } else {
                Long preCar = one1.getPreCar();
                Long platoonId1 = one1.getPlatoonId();


                //找到删除车的后继ID
                LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
                carBindLambdaQueryWrapper2.eq(carBind::getPlatoonId, platoonId1).eq(carBind::getPreCar, one1.getCarId());


                carBind one2 = carBindService.getOne(carBindLambdaQueryWrapper2);

                if (one2 == null) {
                    //如果删除的是最后一辆车,则只需要修改删除该车在表中的记录和修改carplatoon表中的车辆数据-1
                    LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper3 = new LambdaQueryWrapper<>();
                    carBindLambdaQueryWrapper3.eq(carBind::getId, one1.getId());
                    boolean remove1 = carBindService.remove(carBindLambdaQueryWrapper3);
                    if (remove1) {
                        //修改carplatoon表中的车辆数据-1，先找出该车队有多少人
                        LambdaQueryWrapper<carPlatoon> carPlatoonLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                        carPlatoonLambdaQueryWrapper1.eq(carPlatoon::getId, one1.getPlatoonId());
                        carPlatoon one11 = carPlatoonService.getOne(carPlatoonLambdaQueryWrapper1);
                        Integer carNum = one11.getCarNum();
                        //更新车队中的车的数据-1
                        UpdateWrapper<carPlatoon> carPlatoonUpdateWrapper = new UpdateWrapper<>();
                        carPlatoonUpdateWrapper.eq("id", one1.getPlatoonId()).set("car_num", carNum - 1);
                        carPlatoonService.update(null, carPlatoonUpdateWrapper);
                        return R.success("删除用户成功", null);
                    }
                } else {
                    Long id = one2.getId();

                    //更新删除的车的 后面的车 的前驱车 为删除车的 前面的车，即1 <-- 2 <-- 3 => 1 <-- 3

                    UpdateWrapper<carBind> carBindWrapper = new UpdateWrapper<>();
                    carBindWrapper.eq("id", id).set("pre_car", preCar);
                    carBindService.update(null, carBindWrapper);
                    //删除该车在carbind中的记录

                    LambdaQueryWrapper<carBind> carBindLambdaQueryWrapper3 = new LambdaQueryWrapper<>();
                    carBindLambdaQueryWrapper3.eq(carBind::getId, one1.getId());
                    boolean remove1 = carBindService.remove(carBindLambdaQueryWrapper3);
                    if (remove1) {
                        //修改carplatoon表中的车辆数据-1
                        //修改carplatoon表中的车辆数据-1，先找出该车队有多少人
                        LambdaQueryWrapper<carPlatoon> carPlatoonLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                        carPlatoonLambdaQueryWrapper1.eq(carPlatoon::getId, one1.getPlatoonId());
                        carPlatoon one11 = carPlatoonService.getOne(carPlatoonLambdaQueryWrapper1);
                        Integer carNum = one11.getCarNum();
                        //更新车队中的车的数据-1
                        UpdateWrapper<carPlatoon> carPlatoonUpdateWrapper = new UpdateWrapper<>();
                        carPlatoonUpdateWrapper.eq("id", one1.getPlatoonId()).set("car_num", carNum - 1);
                        carPlatoonService.update(null, carPlatoonUpdateWrapper);
                        return R.success("删除用户成功", null);
                    }
                }


            }


        }
        return R.error("退出失败");
    }


}
